Working with Servlet Listeners and Web Application Events
Course: Advanced Java Training
Topic: Working with Servlet Listeners and Web Application Events
Course Link: Advanced Java Training Course
Demo Link: Register for a Course Demo
Website: JustAcademy
1. Introduction to Servlet Listeners
Servlet listeners are Java components that monitor events occurring during the lifecycle of a web application, HTTP session, or servlet request. When a specific event occurs, the servlet container automatically invokes the corresponding listener method.
Listeners help developers respond to application events without repeatedly writing the same logic inside servlets. They are commonly used for application initialization, session tracking, request monitoring, shared application data management, and resource cleanup.
For example, an online shopping application may need to track how many users currently have active sessions. An HttpSessionListener can increase a counter when a session is created and decrease it when a session is destroyed.
Why Are Servlet Listeners Important?
- Lifecycle management: Respond to web application startup and shutdown events.
- Session monitoring: Track session creation and destruction.
- Request monitoring: Perform actions when servlet request processing begins or ends.
- Attribute tracking: Detect when application, session, or request attributes are added, removed, or replaced.
- Resource management: Initialize or release application-level resources at suitable lifecycle points.
- Code organization: Keep event-handling logic separate from servlet business logic.
2. What Are Web Application Events?
A web application event is a notification that a particular change or lifecycle operation has occurred in a web application. The servlet container generates these events and delivers them to registered listener objects.
Events may be related to the application context, HTTP sessions, request processing, or changes to attributes stored in these objects.
Examples of Web Application Events
| Event |
Description |
Typical Use |
| Application initialization |
The web application context is initialized. |
Load application configuration. |
| Application destruction |
The web application context is shutting down. |
Release application-owned resources. |
| Session creation |
A new HTTP session is created. |
Update active-session statistics. |
| Session destruction |
A session is invalidated or expires. |
Update session counters or monitoring data. |
| Request initialization |
Servlet request processing begins. |
Initialize request-scoped monitoring. |
| Attribute addition |
An attribute is added to a context, session, or request. |
Track application state changes. |
| Attribute removal |
An attribute is removed from one of these objects. |
Clean up related application state. |
3. How Servlet Listeners Work
A listener implements one or more listener interfaces provided by the Servlet API. The servlet container creates and registers the listener and invokes its callback methods when matching events occur.
Basic Event Flow
Web Application Event Occurs
|
v
Servlet Container Detects Event
|
v
Registered Listener Is Selected
|
v
Corresponding Listener Method Runs
|
v
Application Responds to the Event
For example, when a session is created, the container invokes the sessionCreated() method of registered HttpSessionListener implementations.
4. Types of Servlet Listeners
The Servlet API provides listener interfaces for different application events. Each interface is designed for a particular event category.
| Listener Interface |
Purpose |
Important Methods |
ServletContextListener |
Monitors web application context initialization and destruction. |
contextInitialized(), contextDestroyed() |
ServletContextAttributeListener |
Monitors changes to context attributes. |
attributeAdded(), attributeRemoved(), attributeReplaced() |
HttpSessionListener |
Monitors HTTP session creation and destruction. |
sessionCreated(), sessionDestroyed() |
HttpSessionAttributeListener |
Monitors changes to session attributes. |
attributeAdded(), attributeRemoved(), attributeReplaced() |
ServletRequestListener |
Monitors the beginning and end of servlet request processing. |
requestInitialized(), requestDestroyed() |
ServletRequestAttributeListener |
Monitors changes to request attributes. |
attributeAdded(), attributeRemoved(), attributeReplaced() |
HttpSessionIdListener |
Monitors changes to a session ID. |
sessionIdChanged() |
HttpSessionActivationListener |
Notifies a session-bound object when its session is activated or passivated. |
sessionDidActivate(), sessionWillPassivate() |
HttpSessionBindingListener |
Notifies an object when it is bound to or unbound from a session. |
valueBound(), valueUnbound() |
Note: The standard session lifecycle listener methods belong to the jakarta.servlet.http package. The exact interfaces available depend on the Servlet API version being used.
5. Understanding ServletContextListener
The ServletContextListener interface monitors the lifecycle of the web application's ServletContext. The context represents application-wide information shared among web components within the same web application.
It provides two main callback methods:
contextInitialized(ServletContextEvent event) — called when the application context is initialized.
contextDestroyed(ServletContextEvent event) — called when the application context is about to be destroyed.
Example: Application Startup and Shutdown Listener
package com.example.listener;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.annotation.WebListener;
@WebListener
public class ApplicationLifecycleListener
implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
ServletContext context = event.getServletContext();
context.setAttribute("applicationName", "Student Portal");
context.setAttribute("applicationStatus", "Running");
System.out.println("Web application initialized");
}
@Override
public void contextDestroyed(ServletContextEvent event) {
System.out.println("Web application is shutting down");
}
}
Explanation
- The
@WebListener annotation registers the listener for the web application.
- The container invokes
contextInitialized() when the context is initialized.
getServletContext() retrieves the application context associated with the event.
setAttribute() stores application-wide values that other web components can retrieve.
- The container invokes
contextDestroyed() when the context is shutting down.
Important: Context attributes are shared application state. Avoid placing user-specific or sensitive data in them, and use thread-safe objects if multiple requests will read or update shared mutable state.
6. Understanding HttpSessionListener
The HttpSessionListener interface monitors the lifecycle of HTTP sessions. A session allows a web application to maintain user-related state across multiple HTTP requests.
The main methods are:
sessionCreated(HttpSessionEvent event) — called when a new HTTP session is created.
sessionDestroyed(HttpSessionEvent event) — called when a session is invalidated or expires.
Example: Tracking Active Sessions
package com.example.listener;
import jakarta.servlet.annotation.WebListener;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
import java.util.concurrent.atomic.AtomicInteger;
@WebListener
public class ActiveSessionListener implements HttpSessionListener {
private static final AtomicInteger ACTIVE_SESSIONS =
new AtomicInteger(0);
@Override
public void sessionCreated(HttpSessionEvent event) {
int count = ACTIVE_SESSIONS.incrementAndGet();
System.out.println("Session created. Active count: " + count);
}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
int count = ACTIVE_SESSIONS.updateAndGet(
current -> Math.max(0, current - 1)
);
System.out.println("Session destroyed. Active count: " + count);
}
public static int getActiveSessionCount() {
return ACTIVE_SESSIONS.get();
}
}
Explanation
- The listener implements
HttpSessionListener.
- The
sessionCreated() method increases the counter.
- The
sessionDestroyed() method decreases the counter.
AtomicInteger makes individual counter operations thread-safe.
- The getter allows other code to retrieve the current counter value.
Important limitations: This counter is local to one application instance. It is not a reliable global count in a multi-server deployment, and sessions may not be created until code or configuration actually requires them. For production-wide session analytics, use a shared monitoring or distributed counting system where appropriate.
7. Understanding ServletRequestListener
The ServletRequestListener interface receives notifications when a servlet request is initialized and when request processing is completed by the web application components.
It defines two methods:
requestInitialized(ServletRequestEvent event) — called when a request is initialized for processing.
requestDestroyed(ServletRequestEvent event) — called when the request is about to go out of scope.
Example: Request Lifecycle Monitoring
package com.example.listener;
import jakarta.servlet.ServletRequestEvent;
import jakarta.servlet.ServletRequestListener;
import jakarta.servlet.annotation.WebListener;
import jakarta.servlet.http.HttpServletRequest;
@WebListener
public class RequestLifecycleListener
implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent event) {
if (event.getServletRequest() instanceof HttpServletRequest) {
HttpServletRequest request =
(HttpServletRequest) event.getServletRequest();
System.out.println(
"Request started: " + request.getMethod()
+ " " + request.getRequestURI()
);
}
}
@Override
public void requestDestroyed(ServletRequestEvent event) {
System.out.println("Request processing completed");
}
}
When Is This Listener Useful?
- Monitoring request lifecycle events.
- Recording request-level diagnostics.
- Associating non-sensitive metadata with a request.
- Supporting request-scoped tracking and cleanup.
For detailed timing around a downstream servlet or filter chain, a filter is often a more suitable choice because it can measure time immediately before and after chain.doFilter().
8. Understanding Attribute Listeners
Servlet context, session, and request objects can store attributes as named objects. Attribute listeners monitor changes to these attributes.
Attribute Event Methods
| Method |
When It Is Called |
attributeAdded() |
When an attribute is added. |
attributeRemoved() |
When an attribute is removed. |
attributeReplaced() |
When an existing attribute value is replaced. |
Example: Monitoring Session Attribute Changes
package com.example.listener;
import jakarta.servlet.annotation.WebListener;
import jakarta.servlet.http.HttpSessionAttributeListener;
import jakarta.servlet.http.HttpSessionBindingEvent;
@WebListener
public class SessionAttributeListenerExample
implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
System.out.println(
"Session attribute added: " + event.getName()
);
}
@Override
public void attributeRemoved(HttpSessionBindingEvent event) {
System.out.println(
"Session attribute removed: " + event.getName()
);
}
@Override
public void attributeReplaced(HttpSessionBindingEvent event) {
System.out.println(
"Session attribute replaced: " + event.getName()
);
}
}
This listener monitors changes to session attributes. The event contains information about the session and the attribute name. For replacement events, the event's value methods should be interpreted according to the API's replacement-event semantics; the previous value can be retrieved from the event where applicable.
For security and privacy, avoid printing attribute values when they may contain personal data, credentials, tokens, or other confidential information.
9. Understanding ServletContext Attributes
The ServletContext can store attributes that are available to components in the same web application. These are useful for shared configuration or application-wide service references.
Example: Context Attribute Listener
package com.example.listener;
import jakarta.servlet.ServletContextAttributeEvent;
import jakarta.servlet.ServletContextAttributeListener;
import jakarta.servlet.annotation.WebListener;
@WebListener
public class ContextAttributeListenerExample
implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent event) {
System.out.println(
"Context attribute added: " + event.getName()
);
}
@Override
public void attributeRemoved(ServletContextAttributeEvent event) {
System.out.println(
"Context attribute removed: " + event.getName()
);
}
@Override
public void attributeReplaced(ServletContextAttributeEvent event) {
System.out.println(
"Context attribute replaced: " + event.getName()
);
}
}
Whenever a context attribute is added, removed, or replaced, the container notifies registered listeners. These events can help diagnose application configuration changes and track shared state.
10. Registering Listeners with @WebListener
The @WebListener annotation is a convenient way to register a listener class. The class must implement a supported listener interface.
Example
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.annotation.WebListener;
@WebListener
public class StartupListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
System.out.println("Application started");
}
}
Ensure annotation scanning is enabled and supported by the application configuration. If a listener is not discovered, verify the package, deployment configuration, API version, and server logs.
11. Registering Listeners Using web.xml
Listeners can also be declared in the deployment descriptor located at WEB-INF/web.xml. This approach is useful when an application uses centralized XML configuration.
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
version="6.0">
<listener>
<listener-class>
com.example.listener.ApplicationLifecycleListener
</listener-class>
</listener>
<listener>
<listener-class>
com.example.listener.ActiveSessionListener
</listener-class>
</listener>
</web-app>
The XML fragment illustrates the listener declaration structure. For a complete deployment descriptor, use the correct schema declaration and version for the Servlet API supported by your application server.
Use annotation-based registration or XML-based registration deliberately. Do not register the same listener through multiple mechanisms unless you have confirmed the intended behavior.
12. Understanding Event Objects
When the container invokes a listener method, it supplies an event object that provides access to the object associated with the event.
| Event Class |
Associated Object |
Common Access Method |
ServletContextEvent |
Web application context |
getServletContext() |
HttpSessionEvent |
HTTP session |
getSession() |
ServletRequestEvent |
Servlet request and context |
getServletRequest(), getServletContext() |
ServletContextAttributeEvent |
Context attribute change |
getName(), getValue() |
HttpSessionBindingEvent |
Session attribute change |
getSession(), getName(), getValue() |
ServletRequestAttributeEvent |
Request attribute change |
getName(), getValue() |
13. Servlet Listeners vs Servlet Filters
Listeners and filters both support cross-cutting web application behavior, but they respond to different mechanisms.
| Feature |
Servlet Listener |
Servlet Filter |
| Primary purpose |
React to application, session, request, or attribute events. |
Intercept and process requests and responses. |
| Invocation |
Called automatically when a matching event occurs. |
Called for requests matching its mappings and dispatcher configuration. |
| Request continuation |
Does not use a filter chain. |
Uses FilterChain to continue request processing. |
| Typical use |
Application startup, session tracking, attribute monitoring. |
Logging, request checks, authentication, encoding. |
| Request/response wrapping |
Not its normal responsibility. |
Can wrap request or response objects. |
| Lifecycle callback examples |
contextInitialized(), sessionCreated() |
init(), doFilter(), destroy() |
14. Servlet Listeners vs Servlets
| Feature |
Servlet |
Listener |
| Purpose |
Handles requests and implements web endpoint behavior. |
Responds to lifecycle or attribute events. |
| Trigger |
Usually invoked through servlet mapping and request dispatch. |
Invoked by the container when a relevant event occurs. |
| Common methods |
doGet(), doPost(), service() |
contextInitialized(), sessionCreated(), requestInitialized() |
| Typical example |
Display a student record or process a login request. |
Track sessions or initialize shared application state. |
15. Listener Execution Order and Lifecycle Considerations
The servlet container manages listener creation and event delivery. Multiple listeners may receive the same event. Where ordering matters, follow the rules of the Servlet API and the application's registration configuration.
- Context initialization listeners are called before filters and servlets are initialized.
- Context destruction listeners are called after the application's servlets and filters have been destroyed.
- For context lifecycle listeners declared in order, initialization callbacks follow declaration order and destruction callbacks follow reverse order.
- Do not assume that every listener is called for every request; each listener only receives events covered by its interface and registration.
- Listener callbacks should be short and predictable because expensive work can affect startup, shutdown, or request processing.
16. Practical Project: Student Portal Event Monitoring
Project objective: Build a simple monitoring feature for a Student Portal application using servlet listeners.
Requirements
- Log when the web application starts.
- Store the application name in the servlet context.
- Track session creation and destruction.
- Log when a request begins and ends.
- Monitor additions and removals of selected session attributes.
Implementation Plan
- Create a Java web application and configure a compatible Servlet API.
- Create an
ApplicationLifecycleListener implementing ServletContextListener.
- Create an
ActiveSessionListener implementing HttpSessionListener.
- Create a
RequestLifecycleListener implementing ServletRequestListener.
- Create a session attribute listener if attribute monitoring is required.
- Register the listener classes using
@WebListener or web.xml.
- Deploy the application on a compatible servlet container.
- Open the application, create a session, add an attribute, and invalidate the session.
- Inspect the server console and confirm that the expected events are logged.
Illustrative Console Output
Web application initialized
Request started: GET /student-portal/home
Session created. Active count: 1
Session attribute added: student
Request processing completed
Session destroyed. Active count: 0
Web application is shutting down
The actual order depends on when the application creates sessions, adds attributes, and processes requests. The output above is only an example.
17. Best Practices for Servlet Listeners
- Use the listener interface that matches the event you need to monitor.
- Keep listener callbacks focused and avoid performing lengthy operations synchronously.
- Initialize application-wide resources in an appropriate startup mechanism and release resources during shutdown.
- Use thread-safe techniques when maintaining shared mutable state.
- Do not assume that a static counter represents all sessions across multiple application instances.
- Avoid storing sensitive information in application-wide context attributes.
- Do not log passwords, authentication tokens, session IDs, or private attribute values.
- Handle exceptions and resource cleanup carefully.
- Verify that listeners are registered only once.
- Use the Servlet API namespace compatible with the deployed server.
- Test application startup, shutdown, session timeout, explicit invalidation, and attribute replacement.
18. Common Errors and Troubleshooting
| Problem |
Possible Cause |
Solution |
| Listener is not called |
Listener registration is missing or annotation discovery is not working. |
Check @WebListener, web.xml, deployment settings, and server logs. |
| Compilation errors in imports |
The project uses a different Servlet API namespace. |
Use jakarta.servlet or javax.servlet as required by the server version. |
| Session count is incorrect |
Counter is not thread-safe, sessions are created lazily, or the application runs on multiple instances. |
Use thread-safe updates and an appropriate shared monitoring strategy. |
| Application startup is slow |
Listener performs expensive initialization synchronously. |
Reduce startup work and move suitable tasks to a managed background mechanism. |
| Listener appears to execute twice |
Duplicate registration or multiple distinct events are being logged. |
Check annotations, XML configuration, and the event sequence. |
| Context attribute is unexpectedly changed |
Multiple components modify shared state. |
Review ownership, synchronization, and application configuration. |
| Session destruction event seems delayed |
The session has not yet timed out or been invalidated. |
Test explicit invalidation and verify session timeout configuration. |
19. Practice Exercises
- Create a
ServletContextListener that prints application startup and shutdown messages.
- Store an application name in the servlet context and retrieve it from a servlet.
- Create an
HttpSessionListener that tracks active sessions.
- Create a
ServletRequestListener that logs request initialization and destruction.
- Implement an
HttpSessionAttributeListener to observe session attribute changes.
- Register a listener using
web.xml rather than annotations.
- Compare listener behavior during session timeout and explicit invalidation.
- Investigate how listener ordering affects application initialization and cleanup.
- Write a short report explaining when to use a filter instead of a listener.
20. Interview Questions and Answers
Q1. What is a Servlet Listener?
Answer: A Servlet Listener is a Java component that receives notifications when specific web application lifecycle or attribute events occur.
Q2. What is a web application event?
Answer: It is a notification that an event such as context initialization, session creation, request initialization, or attribute modification has occurred.
Q3. What is ServletContextListener?
Answer: It monitors web application context initialization and destruction through contextInitialized() and contextDestroyed().
Q4. What is HttpSessionListener?
Answer: It monitors HTTP session creation and destruction through sessionCreated() and sessionDestroyed().
Q5. What is ServletRequestListener?
Answer: It receives notifications when servlet request processing is initialized and when the request is about to go out of scope.
Q6. What is the purpose of @WebListener?
Answer: It declares a supported listener class for automatic registration by a compatible servlet container.
Q7. Can one class implement multiple listener interfaces?
Answer: Yes. A class can implement multiple compatible listener interfaces and receive the corresponding events.
Q8. What is the difference between a listener and a filter?
Answer: A listener reacts to lifecycle or attribute events, while a filter intercepts request and response processing and can continue the chain through chain.doFilter().
Q9. What is ServletContext?
Answer: It represents the web application's shared context and provides access to application-wide attributes and configuration.
Q10. What happens when an HTTP session is destroyed?
Answer: The container notifies registered session lifecycle listeners through sessionDestroyed() when the session is destroyed.
Q11. What are attribute listeners used for?
Answer: They monitor when attributes are added, removed, or replaced in a servlet context, HTTP session, or servlet request.
Q12. Can listener methods access event information?
Answer: Yes. The container supplies event objects that provide access to the associated context, session, request, or attribute information.
Q13. Why should shared counters be thread-safe?
Answer: Multiple request threads can trigger listener callbacks concurrently. Thread-safe updates help prevent lost or inconsistent counter changes.
Q14. When should a listener release resources?
Answer: Application-owned resources should be released at the appropriate lifecycle shutdown point, commonly through contextDestroyed() for resources initialized at application startup.
Q15. How can listeners be registered?
Answer: Supported approaches include the @WebListener annotation, declaration in web.xml, and programmatic registration where supported.
21. Quick Revision Checklist
- Servlet listeners monitor application, session, request, and attribute events.
ServletContextListener monitors application initialization and destruction.
HttpSessionListener monitors session creation and destruction.
ServletRequestListener monitors request initialization and destruction.
- Attribute listeners monitor attribute additions, removals, and replacements.
@WebListener and web.xml are common registration mechanisms.
- Event objects provide access to the objects associated with an event.
- Listeners and filters serve different purposes.
- Shared mutable state must be managed safely across concurrent requests.
- Use compatible Servlet API imports and container versions.
22. Conclusion
Servlet listeners and web application events are essential concepts in Advanced Java web development. They allow developers to react automatically to application startup and shutdown, session lifecycle changes, request lifecycle events, and attribute modifications.
By using ServletContextListener, HttpSessionListener, ServletRequestListener, and attribute listeners appropriately, developers can organize lifecycle management and monitoring logic outside their servlets. Combining listeners with filters and servlets helps create maintainable, modular, and reliable enterprise web applications.
Continue learning with the Advanced Java Training Course, register through the course demo page, or explore the JustAcademy website.